#ifndef ExpressionsManager_h
#define ExpressionsManager_h

//à voir... si on laisse comme ça
//#ifdef SymbolTablesManager
//#undef SymbolTablesManager
//#ifdef IdentTable
//#undef IdentTable

#include "Expression.hpp"
#include "IdentTable.hpp"
#include "SymbolTablesManager.hpp"
#include "Type.hpp"
#include "Value.hpp"

/**
 * Class used as a factory of Expressions
 */
class ExpressionsManager {

private:
	IdentTable* identTable;
	SymbolTablesManager* symbolTablesManager;


	Expression* newNonCalculatedExpression(Type* tokenType, int identTempResult, CodeContainer* code);

public:
	/**
	 * Constructs an ExpressionsManager which will use the specified IdentTable
	 * and SymbolTablesManager to create temporary symbols for the results of
	 * operations on Expressions
	 * @param identTable
	 * @param symbolTablesManager
	 */
	ExpressionsManager(IdentTable* identTable, SymbolTablesManager* symbolTablesManager);

	virtual ~ExpressionsManager();


	/**
	 * Constructs a new Expression for a token
	 * @param tokenType
	 * @param tokenvalue
	 * @return a new Expression
	 */
	Expression* newExpressionFromToken(Type* tokenType, Value* tokenValue);

	/**
	 * Constructs a new Expression for Nil
	 * @return a new Expression
	 */
	Expression* newExpressionFromNil();

	/**
	 * Constructs a new calculated Expression
	 * @param tokenType
	 * @param tokenvalue
	 * @return a new Expression
	 */
	Expression* newCalculatedExpression(Type* tokenType, Value* tokenValue);

	/**
	 * Generate a new Expression calculating : (expression1 binaryOperator expression2)
	 * @param binaryOperator
	 * @param expression1
	 * @param expression2
	 * @return a new Expression
	 */
	Expression* binaryOperation(Expression* expression1, CodeInstruction binaryOperator, Expression* expression2);

	/**
	 * Generate a new Expression calculating : (operator expression)
	 * @param unaryOperator
	 * @param expression
	 * @return a new Expression
	 */
	Expression* unaryOperation(CodeInstruction unaryOperator, Expression* expression);



};

#endif /* ExpressionsManager_h */
